// Package controllers 包含应用程序的控制器逻辑。
// 本文件用于处理用户认证相关的 HTTP 请求。
package controllers

import (
	"exchangeapp/global" // 导入全局变量包，用于访问数据库实例
	"exchangeapp/models" // 导入模型包，用于操作数据库表
	"exchangeapp/utils"  // 导入工具包，用于密码哈希和 JWT 生成
	"net/http"           // 提供 HTTP 请求和响应的相关功能

	"github.com/gin-gonic/gin" // Gin 是一个轻量级的 Web 框架
)

// Register 用户注册
// @Summary 用户注册
// @Description 接收用户注册信息并存储到数据库
// @Tags 用户认证
// @Accept json
// @Produce json
// @Param user body models.User true "用户信息"
// @Success 200 {object} gin.H "注册成功消息"
// @Failure 400 {object} gin.H "请求数据格式错误"
// @Failure 500 {object} gin.H "服务器错误"
// @Router /register [post]
func Register(ctx *gin.Context) {
	// 声明一个 User 结构体变量，用于接收请求数据
	var user models.User

	// 将请求体中的 JSON 数据绑定到 user 变量
	if err := ctx.ShouldBindJSON(&user); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 对用户密码进行哈希处理
	hashedPwd, err := utils.HashPassword(user.Password)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	user.Password = hashedPwd

	// 生成 JWT 令牌
	token, err := utils.GenerateJWT(user.Username)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 自动迁移用户表结构
	if err := global.Db.AutoMigrate(&user); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 将用户信息插入数据库
	if err := global.Db.Create(&user).Error; err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 返回成功消息和 JWT 令牌
	ctx.JSON(http.StatusOK, gin.H{"token": token})
}

// Login 用户登录
// @Summary 用户登录
// @Description 验证用户凭据并返回 JWT 令牌
// @Tags 用户认证
// @Accept json
// @Produce json
// @Param credentials body object true "用户名和密码"
// @Success 200 {object} gin.H "登录成功消息和 JWT 令牌"
// @Failure 400 {object} gin.H "请求数据格式错误"
// @Failure 401 {object} gin.H "认证失败"
// @Failure 500 {object} gin.H "服务器错误"
// @Router /login [post]
func Login(ctx *gin.Context) {
	// 声明一个结构体用于接收登录凭据
	var input struct {
		Username string `json:"username"` // 用户名
		Password string `json:"password"` // 密码
	}

	// 将请求体中的 JSON 数据绑定到 input 变量
	if err := ctx.ShouldBindJSON(&input); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 查询数据库中的用户信息
	var user models.User
	if err := global.Db.Where("username = ?", input.Username).First(&user).Error; err != nil {
		ctx.JSON(http.StatusUnauthorized, gin.H{"error": "wrong credentials"})
		return
	}

	// 验证密码是否正确
	if !utils.CheckPassword(input.Password, user.Password) {
		ctx.JSON(http.StatusUnauthorized, gin.H{"error": "wrong credentials"})
		return
	}

	// 生成 JWT 令牌
	token, err := utils.GenerateJWT(user.Username)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 返回成功消息和 JWT 令牌
	ctx.JSON(http.StatusOK, gin.H{"token": token})
}
